#ifndef TRACER_H
#define TRACER_H

#include <string>
#include <chrono>
#include <memory>
#include <map>
#include <vector>
#include <mutex>

// 定义追踪上下文
struct SpanContext {
    std::string traceId;     // 追踪ID
    std::string spanId;      // 当前span ID
    std::string parentSpanId;// 父span ID
    
    static SpanContext createRandom();  // 创建随机上下文
    static SpanContext fromHeaders(const std::map<std::string, std::string>& headers); // 从请求头解析上下文
    
    std::map<std::string, std::string> toHeaders() const; // 转换为请求头
};

// 定义追踪Span
class Span {
public:
    Span(const std::string& operationName, const SpanContext& context);
    ~Span();
    
    // 设置标签
    void setTag(const std::string& key, const std::string& value);
    
    // 记录日志
    void log(const std::string& event, const std::string& payload = "");
    
    // 完成Span
    void finish();
    
    // 获取上下文
    const SpanContext& context() const;
    
private:
    std::string operationName_;
    SpanContext context_;
    std::chrono::time_point<std::chrono::system_clock> startTime_;
    std::chrono::time_point<std::chrono::system_clock> endTime_;
    std::map<std::string, std::string> tags_;
    std::vector<std::pair<std::string, std::string>> logs_;
    bool finished_;
};

// 追踪器
class Tracer {
public:
    static Tracer& instance();
    
    // 开始新的Span
    std::shared_ptr<Span> startSpan(const std::string& operationName, 
                                   const SpanContext& parentContext = SpanContext::createRandom());
    
    // 获取当前活跃的Span
    std::shared_ptr<Span> activeSpan();
    
    // 将Span推送到追踪系统
    void reportSpan(const Span& span);
    
    // 初始化追踪器
    void init(const std::string& serviceName, const std::string& collectorUrl);
    
private:
    Tracer() = default;
    ~Tracer() = default;
    
    std::string serviceName_;
    std::string collectorUrl_;
    std::shared_ptr<Span> activeSpan_;
    std::mutex mutex_;
};

// 快捷宏
#define TRACE_FUNCTION() auto span = Tracer::instance().startSpan(__FUNCTION__); \
                        span->setTag("file", __FILE__); \
                        span->setTag("line", std::to_string(__LINE__))

#endif // TRACER_H 